<script setup>
import { io } from "socket.io-client";
import { useRouter } from "vue-router";
import { reactive, ref, getCurrentInstance, onMounted, computed } from "vue";
const { proxy } = getCurrentInstance();
const { $untils } = proxy;
import {
  history,
  addUserJoin,
  addUserList,
  isAddUser,
  userList,
  userIsRead,
} from "@/api/chat";
const router = useRouter();

const state = reactive({
  msgText: "",
  userList: [],
  myUser: null,
  targetUser: null,
});
const chatContent = ref();
const myName = sessionStorage.getItem("name");

const socket = io("http://localhost:3000", {
  query: {
    username: myName,
  },
});

const targetUserName = computed(() => {
  if (state.targetUser) {
    return state.targetUser?.user1 === myName
      ? state.targetUser?.user2
      : state.targetUser?.user1;
  } else {
    return null;
  }
});
// ---------发送消息------------
function sendMsg() {
  if (!state.msgText.length) return;

  // 发送
  socket.emit("privateMsg", {
    from: myName,
    to: state.targetUser,
    message: state.msgText,
    time: new Date().getTime(),
  });
  //页面渲染消息
  $untils.appendMessage(
    {
      message: state.msgText,
      time: new Date().getTime(),
    },
    true
  );
  // 自动滚到聊天底部
  $untils.scrollToBottom(chatContent.value);
  state.msgText = "";
  renderUserList();
}
// ---------接收消息------------
socket.on("privateMsg", (msg) => {
  //页面渲染消息
  $untils.appendMessage({
    message: msg.message,
    time: msg.time,
  });
  // 自动滚到聊天底部
  $untils.scrollToBottom(chatContent.value);
  console.log("接收消息了");

  renderUserList();

  // 双发互相聊天，未读消息一直更新为0
  // 并且最后重新渲染一次列表
  let username =
    state.targetUser?.user1 == myName
      ? state.targetUser?.user2
      : state.targetUser?.user1;

  userIsRead({ myName, toName: username })
    .then((res) => {
      renderUserList();
    })
    .catch((err) => {
      console.log(err);
    });
});

// ---------选择好友聊天------------

function selectUser(item) {
  let username = item.user1 == myName ? item.user2 : item.user1;
  // 查看消息将未读消息归0隐藏
  userIsRead({ myName, toName: username })
    .then((res) => {
      renderUserList();
    })
    .catch((err) => {
      console.log(err);
    });

  initialMask.value = false;

  state.targetUser = item;
  // 查询消息记录并且渲染出来
  history({ username, myName })
    .then((res1) => {
      let res = res1.data;

      chatContent.value.innerHTML = "";
      for (let i = 0; i < res.length; i++) {
        if (res[i].from == myName) {
          $untils.appendMessage(
            {
              message: res[i].message,
              time: res[i].timestamp,
            },
            true
          );
        } else {
          $untils.appendMessage({
            message: res[i].message,
            time: res[i].timestamp,
          });
        }
      }
      // 自动滚动到聊天底部
      $untils.scrollToBottom(chatContent.value);
    })
    .catch((err) => {
      console.log(err);
    });
}

// ---------渲染好友列表-----------
function renderUserList() {
  userList({ myName })
    .then((res) => {
      state.userList = res.data;
      console.log(state.userList);
    })
    .catch((err) => {
      console.log(err);
    });
}

onMounted(() => {
  renderUserList();
});

//---------搜索实现---------------
const searchInput = ref();
function search() {
  if (!searchInput.value) {
    renderUserList();
    return;
  }

  let searchUserList = $untils.searchUserJoinList(
    myName,
    state.userList,
    searchInput.value
  );

  state.userList = searchUserList;
}
//---------蒙版---------------
const initialMask = ref(true);

const showMasking = ref(false);
function masking() {
  showModalAdd.value = false;
  showModalReq.value = false;
  showMasking.value = false;
}

//--------好友请求列表----------
const showModalReq = ref(false);
const reqUserList = ref();
function reqUser() {
  showModalReq.value = true;
  showMasking.value = true;

  addUserList({ myName })
    .then((res) => {
      reqUserList.value = res.data;
    })
    .catch((err) => {
      console.log(err);
    });
}

const hasReqUserList = computed(() => {
  return reqUserList.value?.length > 0;
});

// 拒绝好友请求
function NoAddUser(addUserName) {
  isAddUser({ myName, addUserName, is: false })
    .then((res) => {
      reqUser();
    })
    .catch((err) => {
      console.log(err);
    });
}
// 同意好友请求
function yesAddUser(addUserName) {
  isAddUser({ myName, addUserName, is: true })
    .then((res) => {
      reqUser();
      renderUserList();
      // 向发送好友请求的一方执行刷新好友列表
      socket.emit("agreeUser", { addUserName });
    })
    .catch((err) => {
      console.log(err);
    });
}

socket.on("refreshUserList", () => {
  renderUserList();
});

// ----------添加好友-------------
const addUserName = ref("");
const addUserSuccess = ref(false);
const addUserError = ref(false);
const showModalAdd = ref(false);
const addUserSub = () => {
  let addUserNameVal = addUserName.value;
  // 发送添加好友请求
  addUserJoin({ addUserNameVal, myName })
    .then((res) => {
      addUserError.value = false;
      addUserSuccess.value = true;
    })
    .catch((err) => {
      addUserError.value = true;
    });
};

function addUser() {
  addUserName.value = "";

  addUserSuccess.value = false;
  addUserError.value = false;
  showModalAdd.value = true;
  showMasking.value = true;
}
// ----------退出聊天----------------
function quit() {
  sessionStorage.removeItem("mode");
  sessionStorage.removeItem("name");
  // 断开socketio连接
  socket.disconnect();
  router.push("/login");
}
</script>
<template>
  <div v-if="showMasking" class="masking" @click="masking"></div>
  <div v-if="showModalAdd" class="modal-add">
    <h1>添加好友</h1>
    <input
      type="text"
      placeholder="请输入要添加的好友昵称"
      v-model="addUserName" />
    <span class="addUserError" v-if="addUserError">查无此人</span>
    <span class="addUserSuccess" v-if="addUserSuccess">已发送好友请求</span>

    <button @click="addUserSub">添加</button>
  </div>
  <div v-if="showModalReq" class="modal-req">
    <div v-show="!hasReqUserList">暂无好友请求</div>
    <ul>
      <li v-for="item in reqUserList">
        <img src="../assets/images/user.png" alt="" />
        <p>{{ item.user2 }}</p>
        <button @click="yesAddUser(item.user2)">同意</button>
        <button @click="NoAddUser(item.user2)">拒绝</button>
      </li>
    </ul>
  </div>

  <div class="container">
    <div class="leftSide">
      <!--header-->
      <div class="header">
        <div class="userimg">
          <img src="@/assets/images/用户.png" class="cover" />
        </div>
        <p>{{ myName }}</p>
        <button @click="quit">退出</button>
        <!-- <ul class="nav_icons">
          <li><img src="@/assets/images/消息.png" /></li>
          <li><img src="@/assets/images/更多.png" /></li>
        </ul> -->
      </div>
      <!--search-->
      <div class="add_chat">
        <button class="addUser" @click="addUser">添加好友</button>
        <button class="reqUser" @click="reqUser">好友请求</button>
      </div>
      <div class="search_chat">
        <div>
          <input
            type="text"
            v-model="searchInput"
            placeholder="搜索"
            @keydown.enter="search" />
          <img style="width: 22px" src="@/assets/images/搜索.png" />
        </div>
      </div>

      <!--ChatList-->
      <div class="chatlist" v-for="item in state.userList" :key="item._id">
        <div
          :class="{
            block: true,
            active: state.targetUser && state.targetUser._id === item._id,
          }"
          @click="selectUser(item)">
          <div v-if="item.to == myName && item.isread != 0" class="unread">
            {{ item.isread }}
          </div>
          <div class="imgbx">
            <img src="@/assets/images/user.png" class="cover" />
          </div>
          <div class="details">
            <div class="listHead">
              <h4>{{ myName == item.user1 ? item.user2 : item.user1 }}</h4>
              <p class="time">
                {{
                  item.msgtime ? $untils.formatTime(new Date(item.msgtime)) : ""
                }}
              </p>
            </div>
            <div class="message_p">
              <p>{{ item.lastmsg ?? "暂无消息" }}</p>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="rightSide">
      <div v-show="initialMask" class="rightMasking">开始聊天吧</div>
      <div class="header">
        <div class="imgText">
          <div class="userimg">
            <img src="@/assets/images/user.png" class="cover" />
          </div>
          <h4>{{ targetUserName }}</h4>
        </div>
      </div>
      <!--chatbox-->
      <div class="chatBox test-1" ref="chatContent"></div>

      <!--chat input-->
      <div class="chatbox_input">
        <div class="instrument">
          <img style="width: 30px" src="@/assets/images/表情.png" />
          <img style="width: 30px" src="@/assets/images/语音.png" />
        </div>
        <div>
          <textarea
            type="text"
            v-model="state.msgText"
            @keydown.enter="sendMsg"></textarea>
        </div>
        <div>
          <button class="sendMsg" @click="sendMsg">发送</button>
        </div>
      </div>
    </div>
  </div>
</template>
<style>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Open Sans", sans-serif;
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background-image: url("@/assets/images/1.png");
  background-size: cover;
}
.container {
  border-radius: 20px;
  opacity: 0.8;
  overflow: hidden;
  position: relative;
  width: 60vw;
  max-width: 100%;
  height: calc(100vh - 100px);
  background: #fff;
  box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.06), 0 2px 5px 0 rgba(0, 0, 0, 0.06);
  display: flex;
}
.container .leftSide {
  position: relative;
  flex: 25%;
  background: #fff;
  border-right: 1px solid rgba(0, 0, 0, 0.2);
}
.container .rightSide {
  position: relative;
  flex: 75%;
  background: #e5ddd5;
}
.container .rightside::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: url(img6-bg.jpg);
  opacity: 0.06;
}
.header {
  position: relative;
  top: 0;
  width: 100%;
  height: 10%;
  background: #ededed;
  display: flex;
  align-items: center;
  padding: 0 15px;
}
.header button {
  margin: 0 0 0 auto;
  background-color: #e7e9ec;
  border-radius: 10px;
  width: 50px;
  height: 30px;
  border: 1px solid #cbcdd1;
}
.header button:hover {
  background-color: rgba(0, 255, 13, 0.3);
}
.userimg {
  position: relative;
  width: 40px;
  height: 40px;
  overflow: hidden;
  border-radius: 50%;
  cursor: pointer;
}
.cover {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.nav_icons {
  display: flex;
}
.nav_icons li {
  display: flex;
  list-style: none;
  cursor: pointer;
  color: #51585c;
  font-size: 1.5em;
  margin-left: 22px;
}
.search_chat,
.add_chat {
  position: relative;
  width: 100%;
  height: 50px;
  background: #f6f6f6;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0 15px;
}
.search_chat div {
  width: 100%;
}
.search_chat div input {
  width: 100%;
  outline: none;
  border: none;
  background: #fff;
  padding: 6px;
  height: 38px;
  border-radius: 30px;
  font-size: 14px;
  padding-left: 40px;
}
.search_chat div input::placeholder {
  color: #bbb;
}
.search_chat div img {
  /* width: 10px;
  height: 10px; */
  position: absolute;
  left: 30px;
  top: 14px;
  font-size: 1.5em;
}
.add_chat .addUser {
  width: 100px;
  height: 30px;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  border: 1px solid #cccdcf;
}

.add_chat .reqUser {
  width: 100px;
  height: 30px;
  /* border-radius: 10px; */
  border: 1px solid #cccdcf;
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
}

.chatlist {
  position: relative;
  height: calc(100%-110px);
  overflow-y: auto;
}
.chatlist .block {
  position: relative;
  width: 100%;
  display: flex;
  align-items: center;
  padding: 15px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.chatlist .block.active {
  background: #6d69694d;
}
.chatlist .block:hover {
  background: #f5f5f5;
}
.chatlist .block .imgbx {
  /* height: 45px; */
  position: relative;
  min-width: 45px;
  height: 45px;
  overflow: hidden;
  border-radius: 50%;
  margin-right: 10px;
}
.chatlist .block .details {
  position: relative;
  width: 100%;
}
.chatlist .block .details .listHead {
  display: flex;
  justify-content: space-between;
  margin-bottom: 5px;
}
.chatlist .block .details .listHead h4 {
  font-size: 1.1em;
  font-weight: 600;
  color: #111;
}
.chatlist .block .details .listHead .time {
  font-size: 0.75em;
  color: #aaa;
}
.chatlist .block .details .listHead .time {
  color: #111;
}

.message_p {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.message_p p {
  color: #aaa;
  display: -webkit-box;
  -webkit-line-break: 1;
  font-size: 0.9em;
  overflow: hidden;
  text-overflow: ellipsis;
}
.message_p b {
  background-color: red;
  color: #fff;
  min-width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 0.75em;
}
.imgText {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
}
.imgText h4 {
  font-weight: 500;
  line-height: 1.2em;
  margin-left: 15px;
}
.imgText h4 span {
  font-size: 0.8em;
  color: #555;
}
.chatBox {
  position: absolute;
  background-color: #f5f5f5;
  top: 10%;
  width: 100%;
  height: 65%;
  border-bottom: 2px solid #eeeeee;
  padding: 50px;
  overflow-y: auto;
}
.message {
  position: relative;
  display: flex;
  width: 100%;
  margin: 5px 0;
}
.message p {
  position: relative;
  right: 0;
  text-align: right;
  max-width: 65%;
  padding: 12px;
  background: #dcf8c6;
  border-radius: 10px;
  font-size: 0.9em;
}
.message p::before {
  content: "";
  position: absolute;
  top: 0;
  right: -12px;
  width: 20px;
  height: 20px;
  background: linear-gradient(
    135deg,
    #dcf8c6 0%,
    #dcf8c6 50%,
    transparent 50%,
    transparent
  );
}
.message p span {
  display: block;
  margin-top: 5px;
  font-size: 0.85em;
  opacity: 0.5;
}
.my_message {
  justify-content: flex-end;
}
.frnd_message {
  justify-content: flex-start;
}
.frnd_message p {
  background: #fff;
  text-align: left;
}
.message.frnd_message p::before {
  content: "";
  position: absolute;
  top: 0;
  left: -12px;
  width: 20px;
  height: 20px;
  background: linear-gradient(
    225deg,
    #fff 0%,
    #fff 50%,
    transparent 50%,
    transparent
  );
}
.chatbox_input {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 25%;
  background: #f5f5f5;
  padding: 15px;
  justify-content: space-between;
  align-items: center;
}
.chatbox_input textarea {
  resize: none;
  background-color: #f5f5f5;
  bottom: 10%;
  left: 0;
  right: 0;
  top: 30%;
  position: absolute;
  margin: 0 20px;
  padding: 10px 20px;
  border: none;
  outline: none;
  /* border-radius: 30px; */
  font-size: 1em;
}
.sendMsg {
  position: absolute;
  padding: 6px 35px;
  border: none;
  background-color: #e9e9e9;
  color: #31c87a;
  font-size: 15px;
  bottom: 10%;
  right: 5%;
  border-radius: 5px;
}
.sendMsg:hover {
  background-color: #d2d2d2;
  color: #06ae56;
}

.test-1::-webkit-scrollbar {
  /*滚动条整体样式*/
  width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
  height: 1px;
}
.test-1::-webkit-scrollbar-thumb {
  /*滚动条里面小方块*/
  border-radius: 10px;
  box-shadow: inset 0 0 5px rgba(204, 199, 199, 0.2);
  background: #cdc9c9;
}
.test-1::-webkit-scrollbar-track {
  /*滚动条里面轨道*/
  box-shadow: inset 0 0 5px #e0dbdb;
  /* border-radius: 10px; */
  background: #ededed;
}

.modal-add,
.modal-req {
  border-radius: 30px;
  padding: 30px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 300px;
  height: 200px;
  z-index: 9;
  background-color: white;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.modal-req {
  height: 400px;
}
.masking {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 2;
  background-color: rgba(0, 0, 0, 0.6);
}
.modal-add h1 {
  margin-bottom: 10px;
}
.modal-add input {
  border-radius: 5px;
  width: 100%;
  height: 30px;
  /* margin: 10px 0; */
}
.modal-add .addUserError {
  color: red;
  font-size: 12px;
}

.modal-add .addUserSuccess {
  color: rgb(0, 255, 17);
  font-size: 12px;
}

.modal-add button {
  margin-top: 10px;
  border: none;
  width: 50%;
  height: 30px;
  border-radius: 5px;
  background-color: black;
  color: white;
}
.modal-req ul {
  width: 100%;
  height: 100%;
  overflow-y: scroll;
}
.modal-req ul li {
  list-style-type: none;
  display: flex;
  padding: 5px 10px;
  margin-bottom: 5px;
  border-radius: 22px;
  background-color: rgba(0, 0, 0, 0.2);
  align-items: center;
}
.modal-req ul li img {
  width: 30px;
  height: 30px;
  border-radius: 50%;
}
.modal-req ul li p {
  margin: 0 auto 0 0;
}
.modal-req ul li button {
  border: none;
  padding: 5px;
  border-radius: 5px;
  margin: 0 1px;
}
.modal-req ul li button:hover {
  background-color: rgba(85, 255, 0, 0.2);
}
.rightMasking {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 8;
  background-color: black;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 30px;
}
.unread {
  position: absolute;
  right: 0px;
  top: 0px;
  width: 15px;
  height: 15px;
  background-color: red;
  color: white;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 12px;
}
</style>
